﻿using LSFTP;
using LSFTP.model;
using LSFTP.MultithreadFileDownload;
using Rainbow.core;
using Rainbow.model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Rainbow.view
{
    /// <summary>
    /// DownloadFileDlg.xaml 的交互逻辑
    /// </summary>
    public partial class DownloadFileDlg : Window
    {
        private DownloadFileDlgViewModel windowViewModel;

        private DownLoadFile dlf;

        private SFTPClient sftp;

        private string localPath;
        private List<FTPFileInfo> remoteFiles;

        public DownloadFileDlg()
        {
            InitializeComponent();

            dlf = new DownLoadFile();
            dlf.ThreadNum = TW_App.globalSetting.downloadThreadNum;
            dlf.doSendMsg += UpdateListView;

            this.Loaded += new RoutedEventHandler(Window_Loaded);

            this.btnOK.Click += new RoutedEventHandler(OK_Click);
            this.btnCancel.Click += new RoutedEventHandler(Cancel_Click);

            windowViewModel = new DownloadFileDlgViewModel();
            this.DataContext = windowViewModel;
        }

        public DownloadFileDlg(List<FTPFileInfo> remoteFiles, string localPath, SFTPClient sftp) : this()
        {
            this.sftp = sftp;
            this.localPath = localPath;
            this.remoteFiles = remoteFiles;

            this.btnOK.IsEnabled = false;
        }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            StartDown();
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            if(windowViewModel.finishCount == windowViewModel.totalCount)
            {
                this.DialogResult = true;
            }
            else
            {
                MessageBoxResult result = System.Windows.MessageBox.Show("下载未完成，是否确认停止下载","提示",MessageBoxButton.YesNo,MessageBoxImage.Question);
                if(MessageBoxResult.Yes == result)
                {
                    dlf.StopDown();
                    this.DialogResult= false;
                }
            }
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            if (windowViewModel.finishCount == windowViewModel.totalCount)
            {
                this.DialogResult = true;
            }
            else
            {
                MessageBoxResult result = System.Windows.MessageBox.Show("下载未完成，是否确认停止下载", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);
                if (MessageBoxResult.Yes == result)
                {
                    dlf.StopDown();
                    this.DialogResult = false;
                }
            }
        }

        private void StartDown()
        {
            try
            {
                string rootPath = remoteFiles[0].FullName.Replace(remoteFiles[0].Name, "").Replace("//", "/").Replace("/", "\\");
                if (rootPath.Equals("\\"))
                    rootPath = "\\\\\\\\\\\\\\\\\\\\\\\\";

                foreach (var item in remoteFiles)
                {
                    if (item.IsDirectory)
                    {
                        string lPath = localPath + "\\" + item.Name;
                        if (!Directory.Exists(lPath))
                            Directory.CreateDirectory(lPath);
                        List<FTPFileInfo> list = sftp.GetFileInfoList(item.FullName, "*.*", true, false);

                        foreach (var item1 in list)
                        {
                            string llPath = (localPath + "\\" + item1.FullName.Replace("/", "\\").Replace(rootPath, "")).Replace("\\\\", "\\");
                            if (item1.IsDirectory)
                            {
                                if (!Directory.Exists(llPath))
                                    Directory.CreateDirectory(llPath);
                            }
                            else
                            {
                                string filePath = llPath.Replace(item1.Name, "");
                                if (!Directory.Exists(filePath))
                                    Directory.CreateDirectory(filePath);

                                //var byt = sftp.ReadAllBytes(item1.FullName);
                                //File.WriteAllBytes(llPath, byt);

                                DownloadFileInfoViewModel downloadFileInfoViewModel = new DownloadFileInfoViewModel();
                                downloadFileInfoViewModel.localPath = llPath;
                                downloadFileInfoViewModel.remotePath = item1.FullName;
                                downloadFileInfoViewModel.fileInfo = item1;
                                downloadFileInfoViewModel.index = windowViewModel.infos.Count + 1;
                                windowViewModel.infos.Add(downloadFileInfoViewModel);
                            }
                        }
                    }
                    else
                    {
                        if (!Directory.Exists(localPath))
                            Directory.CreateDirectory(localPath);

                        string localFile = localPath + "\\" + item.Name;

                        DownloadFileInfoViewModel downloadFileInfoViewModel = new DownloadFileInfoViewModel();
                        downloadFileInfoViewModel.localPath = localFile;
                        downloadFileInfoViewModel.remotePath = item.FullName;
                        downloadFileInfoViewModel.fileInfo = item;
                        downloadFileInfoViewModel.index = windowViewModel.infos.Count + 1;
                        windowViewModel.infos.Add(downloadFileInfoViewModel);
                    }
                }

                windowViewModel.totalCount = windowViewModel.infos.Count;
                foreach (var item in windowViewModel.infos)
                {
                    dlf.AddDown(item.remotePath, item.localPath, sftp, item.index - 1);
                }
                dlf.StartDown(dlf.ThreadNum);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("SFTP文件获取失败，原因：{0}", ex.Message));
            }
        }


        private void UpdateListView(DownMsg msg)
        {
            switch (msg.Tag)
            {
                case DownStatus.Start:
                    App.Current.Dispatcher.InvokeAsync((Action)(() =>
                    {
                        windowViewModel.infos[msg.Id].status = "开始下载";
                        windowViewModel.infos[msg.Id].dateTime = DateTime.Now;
                    }));
                    break;
                case DownStatus.GetLength:
                    App.Current.Dispatcher.InvokeAsync((Action)(() =>
                    {
                        windowViewModel.infos[msg.Id].status = "连接成功";
                        windowViewModel.infos[msg.Id].totalSize = msg.LengthInfo;
                    }));
                    break;
                case DownStatus.End:
                case DownStatus.DownLoad:
                    App.Current.Dispatcher.InvokeAsync((Action)(() =>
                    {
                        windowViewModel.infos[msg.Id].completed = msg.SizeInfo;
                        windowViewModel.infos[msg.Id].progress = (int)msg.Progress;
                        windowViewModel.infos[msg.Id].speed = msg.SpeedInfo;
                        windowViewModel.infos[msg.Id].residue = msg.SurplusInfo;
                        if (msg.Tag == DownStatus.DownLoad)
                        {
                            windowViewModel.infos[msg.Id].status = "下载中";
                        }
                        else
                        {
                            windowViewModel.infos[msg.Id].status = "下载完成";
                            windowViewModel.finishCount++;
                            if(windowViewModel.finishCount == windowViewModel.totalCount)
                            {
                                this.btnOK.IsEnabled = true;   
                            }
                            if (windowViewModel.finishCount > windowViewModel.totalCount)
                            {
                                Console.WriteLine(windowViewModel.infos[msg.Id].name + ":" + windowViewModel.finishCount.ToString());
                                windowViewModel.finishCount = windowViewModel.totalCount;
                            }
                        }
                    }));
                    break;
                case DownStatus.Error:
                    App.Current.Dispatcher.InvokeAsync((Action)(() =>
                    {
                        windowViewModel.infos[msg.Id].residue = "失败";
                        windowViewModel.infos[msg.Id].status = msg.ErrMessage;
                    }));
                    break;
            }
        }
    }

    public class DownloadFileDlgViewModel : ViewModelBase
    {
        public DownloadFileDlgViewModel()
        {
            totalCount = 0;
            finishCount = 0;
            infos = new ObservableCollection<DownloadFileInfoViewModel>();
        }

        private ObservableCollection<DownloadFileInfoViewModel> m_infos;
        public ObservableCollection<DownloadFileInfoViewModel> infos
        {
            get { return m_infos; }
            set
            {
                m_infos = value;
                NotifyPropertyChanged();
            }
        }

        private int m_finishCount;
        public int finishCount
        {
            get { return m_finishCount; }
            set
            {
                m_finishCount = value;
                NotifyPropertyChanged();
            }
        }

        private int m_totalCount;
        public int totalCount
        {
            get { return m_totalCount; }
            set
            {
                m_totalCount = value;
                NotifyPropertyChanged();
            }
        }
    }
}
